// 图片格式转换工具

export interface ImageFormat {
  value: string;
  label: string;
  desc: string;
  compression: "极高" | "高" | "中" | "低";
}

export interface ConversionSettings {
  quality: number;
  resizeEnabled: boolean;
  maxWidth: number;
  maxHeight: number;
}

export interface ConversionResult {
  originalSize: number;
  convertedSize: number;
  compressionRatio: number;
  compressionPercentage: number;
}

// 支持的格式
export const SUPPORTED_FORMATS: ImageFormat[] = [
  {
    value: "WEBP",
    label: "WebP",
    desc: "现代格式，体积小，质量高",
    compression: "高",
  },
  {
    value: "JPEG",
    label: "JPEG",
    desc: "通用格式，兼容性好",
    compression: "中",
  },
  { value: "PNG", label: "PNG", desc: "支持透明背景", compression: "低" },
  {
    value: "AVIF",
    label: "AVIF",
    desc: "最新格式，压缩率极高",
    compression: "极高",
  },
];

// 获取格式的压缩比
export function getCompressionRatio(format: string): number {
  const formatInfo = SUPPORTED_FORMATS.find(f => f.value === format);
  if (!formatInfo) return 0.8; // 默认压缩比

  switch (formatInfo.compression) {
    case "极高":
      return 0.3; // AVIF
    case "高":
      return 0.5; // WebP
    case "中":
      return 0.7; // JPEG
    case "低":
      return 0.9; // PNG
    default:
      return 0.8;
  }
}

// 计算转换后的文件大小
export function calculateConvertedSize(
  originalSize: number,
  targetFormat: string,
  settings: ConversionSettings
): ConversionResult {
  // 获取基础压缩比
  let compressionRatio = getCompressionRatio(targetFormat);

  // 应用质量设置
  compressionRatio *= settings.quality / 100;

  // 应用尺寸调整
  if (settings.resizeEnabled) {
    compressionRatio *= 0.8; // 尺寸调整额外压缩
  }

  const convertedSize = Math.round(originalSize * compressionRatio);
  const compressionPercentage = Math.round(
    ((originalSize - convertedSize) / originalSize) * 100
  );

  return {
    originalSize,
    convertedSize,
    compressionRatio,
    compressionPercentage,
  };
}

// 格式化文件大小
export function formatFileSize(bytes: number): string {
  if (bytes === 0) return "0 B";

  const k = 1024;
  const sizes = ["B", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));

  return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + " " + sizes[i];
}

// 真正的图片格式转换
export async function convertImageFormat(
  file: File,
  targetFormat: string,
  settings: ConversionSettings,
  onProgress?: (progress: number) => void
): Promise<File> {
  return new Promise((resolve, reject) => {
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    if (!ctx) {
      reject(new Error("无法创建 Canvas 上下文"));
      return;
    }

    const img = new Image();
    img.onload = () => {
      try {
        // 计算新尺寸
        let { width, height } = img;
        if (settings.resizeEnabled) {
          const ratio = Math.min(
            settings.maxWidth / width,
            settings.maxHeight / height,
            1
          );
          width = Math.round(width * ratio);
          height = Math.round(height * ratio);
        }

        // 设置 Canvas 尺寸
        canvas.width = width;
        canvas.height = height;

        // 绘制图片
        ctx.drawImage(img, 0, 0, width, height);

        // 转换为指定格式
        let mimeType: string;
        let quality = settings.quality / 100;

        switch (targetFormat.toUpperCase()) {
          case "WEBP":
            mimeType = "image/webp";
            break;
          case "JPEG":
            mimeType = "image/jpeg";
            break;
          case "PNG":
            mimeType = "image/png";
            quality = 1; // PNG 不支持质量参数
            break;
          case "AVIF":
            mimeType = "image/avif";
            break;
          default:
            mimeType = "image/webp";
        }

        onProgress?.(50);

        // 转换为 Blob
        canvas.toBlob(
          blob => {
            if (blob) {
              onProgress?.(100);

              // 创建新的 File 对象
              let newFileName: string;
              if (file.name.includes(".")) {
                // 如果原文件名有扩展名，替换扩展名
                newFileName = file.name.replace(
                  /\.[^/.]+$/,
                  `.${targetFormat.toLowerCase()}`
                );
              } else {
                // 如果原文件名没有扩展名，直接添加扩展名
                newFileName = `${file.name}.${targetFormat.toLowerCase()}`;
              }

              // 清理文件名，确保符合存储服务要求
              newFileName = sanitizeFileName(newFileName);

              // 确保文件名不为空
              if (!newFileName || newFileName.trim() === "") {
                newFileName = `converted_image.${targetFormat.toLowerCase()}`;
              }

              const convertedFile = new File([blob], newFileName, {
                type: mimeType,
                lastModified: Date.now(),
              });

              resolve(convertedFile);
            } else {
              reject(new Error("格式转换失败"));
            }
          },
          mimeType,
          quality
        );
      } catch (error) {
        reject(error);
      }
    };

    img.onerror = () => {
      reject(new Error("图片加载失败"));
    };

    // 加载图片
    img.src = URL.createObjectURL(file);
    onProgress?.(25);
  });
}

// 模拟格式转换过程（保留用于兼容性）
export function simulateConversion(
  originalSize: number,
  targetFormat: string,
  settings: ConversionSettings,
  onProgress?: (progress: number) => void
): Promise<ConversionResult> {
  return new Promise(resolve => {
    let progress = 0;

    // 模拟上传阶段 (0-50%)
    const uploadTimer = setInterval(() => {
      if (progress < 50) {
        progress += Math.random() * 15 + 5;
        if (progress > 50) progress = 50;
        onProgress?.(progress);
      } else {
        clearInterval(uploadTimer);

        // 模拟转换阶段 (50-100%)
        const convertTimer = setInterval(() => {
          if (progress < 100) {
            progress += Math.random() * 10 + 5;
            if (progress > 100) progress = 100;
            onProgress?.(progress);
          } else {
            clearInterval(convertTimer);
            const result = calculateConvertedSize(
              originalSize,
              targetFormat,
              settings
            );
            resolve(result);
          }
        }, 300);
      }
    }, 200);
  });
}

// 批量转换
export function batchConvert(
  items: Array<{ originalSize: number; targetFormat: string }>,
  settings: ConversionSettings
): ConversionResult[] {
  return items.map(item =>
    calculateConvertedSize(item.originalSize, item.targetFormat, settings)
  );
}

// 计算总压缩率
export function calculateTotalCompression(results: ConversionResult[]): number {
  if (results.length === 0) return 0;

  const totalOriginal = results.reduce(
    (sum, result) => sum + result.originalSize,
    0
  );
  const totalConverted = results.reduce(
    (sum, result) => sum + result.convertedSize,
    0
  );

  return Math.round(((totalOriginal - totalConverted) / totalOriginal) * 100);
}

// 获取格式建议
export function getFormatRecommendation(useCase: string): ImageFormat {
  switch (useCase) {
    case "web":
      return SUPPORTED_FORMATS.find(f => f.value === "WEBP")!;
    case "photo":
      return SUPPORTED_FORMATS.find(f => f.value === "JPEG")!;
    case "icon":
      return SUPPORTED_FORMATS.find(f => f.value === "PNG")!;
    case "modern":
      return SUPPORTED_FORMATS.find(f => f.value === "AVIF")!;
    default:
      return SUPPORTED_FORMATS.find(f => f.value === "WEBP")!;
  }
}

// 验证和清理文件名，确保符合存储服务要求
export function sanitizeFileName(fileName: string): string {
  if (!fileName || fileName.trim() === "") {
    return "image";
  }

  // 移除或替换不支持的字符
  let sanitized = fileName
    .trim()
    // 移除或替换不支持的字符
    .replace(/[<>:"/\\|?*\x00-\x1f]/g, "_") // 替换 Windows 不支持的字符
    .replace(/[\r\n]/g, "_") // 替换换行符
    .replace(/^[\/\\]/, "") // 移除开头的斜杠
    .replace(/[\/\\]$/, "") // 移除结尾的斜杠
    .replace(/\s+/g, "_") // 替换空格为下划线
    .replace(/_{2,}/g, "_") // 多个连续下划线替换为单个
    .replace(/^_+|_+$/g, ""); // 移除开头和结尾的下划线

  // 确保文件名不为空
  if (!sanitized || sanitized.length === 0) {
    sanitized = "image";
  }

  // 限制文件名长度（考虑扩展名）
  const maxLength = 200; // 留一些余量给扩展名
  if (sanitized.length > maxLength) {
    const ext = sanitized.split(".").pop();
    const nameWithoutExt = sanitized.substring(0, sanitized.lastIndexOf("."));
    sanitized =
      nameWithoutExt.substring(0, maxLength - ext!.length - 1) + "." + ext;
  }

  return sanitized;
}

// 验证转换设置
export function validateSettings(settings: ConversionSettings): {
  valid: boolean;
  errors: string[];
} {
  const errors: string[] = [];

  if (settings.quality < 1 || settings.quality > 100) {
    errors.push("质量设置必须在 1-100 之间");
  }

  if (settings.resizeEnabled) {
    if (settings.maxWidth < 1) {
      errors.push("最大宽度必须大于 0");
    }
    if (settings.maxHeight < 1) {
      errors.push("最大高度必须大于 0");
    }
  }

  return {
    valid: errors.length === 0,
    errors,
  };
}
